import {
  Event,
  Color,
  Material,
  defined,
  createPropertyDescriptor,
  Property,
} from "cesium";
import * as Cesium from "cesium";

/*
 * @Description: 飞线效果（参考开源代码）
 *
 */
class LineFlowMaterialProperty {
  constructor(options) {
    this._definitionChanged = new Event();
    this._color = undefined;
    this._speed = undefined;
    this._percent = undefined;
    this._gradient = undefined;
    this._count = undefined;
    this.color = options.color;
    this.speed = options.speed;
    this.percent = options.percent;
    this.gradient = options.gradient;
    this.count = options.count;
  }

  get isConstant() {
    return false;
  }

  get definitionChanged() {
    return this._definitionChanged;
  }

  getType(time) {
    return Material.LineFlowMaterialType;
  }

  getValue(time, result) {
    if (!defined(result)) {
      result = {};
    }

    result.color = Property.getValueOrDefault(
      this._color,
      time,
      Color.RED,
      result.color
    );
    result.speed = Property.getValueOrDefault(
      this._speed,
      time,
      5.0,
      result.speed
    );
    result.percent = Property.getValueOrDefault(
      this._percent,
      time,
      0.1,
      result.percent
    );
    result.gradient = Property.getValueOrDefault(
      this._gradient,
      time,
      0.01,
      result.gradient
    );
    result.count = Property.getValueOrDefault(
      this._count,
      time,
      0.01,
      result.count
    );
    return result;
  }

  equals(other) {
    return (
      this === other ||
      (other instanceof LineFlowMaterialProperty &&
        Property.equals(this._color, other._color) &&
        Property.equals(this._speed, other._speed) &&
        Property.equals(this._percent, other._percent) &&
        Property.equals(this._gradient, other._gradient) &&
        Property.equals(this._count, other._count))
    );
  }
}

Object.defineProperties(LineFlowMaterialProperty.prototype, {
  color: createPropertyDescriptor("color"),
  speed: createPropertyDescriptor("speed"),
  percent: createPropertyDescriptor("percent"),
  gradient: createPropertyDescriptor("gradient"),
  gradient: createPropertyDescriptor("count"),
});

Cesium.LineFlowMaterialProperty = LineFlowMaterialProperty;
Material.LineFlowMaterialProperty = "LineFlowMaterialProperty";
Material.LineFlowMaterialType = "LineFlowMaterialType";
Material.LineFlowMaterialSource = `
    uniform vec4 color;
    uniform float speed;
    uniform float percent;
    uniform float gradient;
    
    czm_material czm_getMaterial(czm_materialInput materialInput){
      czm_material material = czm_getDefaultMaterial(materialInput);
      vec2 st = materialInput.st;
      float t =fract(czm_frameNumber * speed / 1000.0);
      t *= (1.0 + percent);
      float alpha = smoothstep(t- percent, t, st.s) * step(-t, -st.s);
      alpha += gradient;
      material.diffuse = color.rgb;
      material.alpha = alpha;
      return material;
    }
    `;

Material._materialCache.addMaterial(Material.LineFlowMaterialType, {
  fabric: {
    type: Material.LineFlowMaterialType,
    uniforms: {
      color: new Color(1.0, 0.0, 0.0, 1.0),
      speed: 10.0,
      percent: 0.1,
      gradient: 0.01,
      count: 1,
    },
    source: Material.LineFlowMaterialSource,
  },
  translucent: function (material) {
    return true;
  },
});
